﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Resources;
using System.IO;

using NPOI.HSSF.UserModel;

using ID = System.String;
using Value = System.String;


namespace ResxusEngine
{
    public static class HSSFSheetExtension
    {
        public static HSSFCell Cell(this HSSFSheet sheet, int row, int col)
        {
            HSSFRow dataRow = sheet.GetRow(row);
            if (dataRow == null)
            {
                dataRow = sheet.CreateRow(row);
                if (dataRow.GetCell(col) == null)
                {
                    return dataRow.CreateCell(col);
                }
            }
            else
            {
                if (dataRow.GetCell(col) == null)
                {
                    return dataRow.CreateCell(col);
                }
            }

            return dataRow.GetCell(col);
        }
    }



    public class Writer
    {
        #region Write Helper Functions

        /// <summary>
        /// 리소스 파일을 씁니다. 
        /// </summary>
        /// <param name="outputFileName">출력파일이름</param>
        /// <param name="enumerator">반복자</param>
        public static void WriteResx(string outputFileName, IDictionaryEnumerator enumerator)
        {
            //쓰기             
            using (ResXResourceWriter resxWriter = new ResXResourceWriter(outputFileName))
            {
                //기존 내용 반영
                while (enumerator.MoveNext())
                {
                    resxWriter.AddResource(enumerator.Key.ToString(), enumerator.Value.ToString());
                }
            }
        }

        /// <summary>
        /// 리소스 내용을 엑셀 파일에 저장합니다.
        /// </summary>
        /// <param name="outputFileName">출력 파일이름</param>
        /// <param name="enumerator">출력할 리소스 목록</param>
        /// <param name="fileName">원본 리소스 파일이름</param>
        public static void WriteXlsx(string outputFileName, IDictionaryEnumerator enumerator, string fileName)
        {
            Action<HSSFSheet, IDictionaryEnumerator, int> action = (sheet, dicEnumerator, rowIndex) =>
            {
                sheet.Cell(rowIndex, 0).SetCellValue(enumerator.Key.ToString());
                Value entry = (Value)enumerator.Value;

                try
                {
                    sheet.Cell(rowIndex, 1).SetCellValue(entry);
                }
                catch (System.Exception ex)
                {
                    Common.ErrorHandler(ex);
                }
            };

            FileInfo fi = new FileInfo(fileName);
            string worksheetTitle = fi.Name;

            WriteXlsx(outputFileName, enumerator, worksheetTitle, new string[] { "ResourceID", "Value" }, action);
        }

        /// <summary>
        /// 비교 결과를 결과 엑셀 파일에 저장합니다.
        /// </summary>
        /// <param name="outputFileName">결과 Xlsx 파일</param>
        /// <param name="enumerator">엑셀에 저장할 엔트리 정보가 들어있는 파일</param>
        /// <param name="fileNameA">A 파일이름</param>
        /// <param name="fileNameB">B 파일이름</param>
        public static void WriteXlsx(string outputFileName, IDictionaryEnumerator enumerator, string fileNameA, string fileNameB)
        {
            Action<HSSFSheet, IDictionaryEnumerator, int> action = (sheet, dicEnumerator, rowIndex) =>
            {
                sheet.Cell(rowIndex, 0).SetCellValue(enumerator.Key.ToString());
                Values entry = (Values)enumerator.Value;

                try
                {
                    sheet.Cell(rowIndex, 1).SetCellValue(entry.ValueA);
                    sheet.Cell(rowIndex, 2).SetCellValue(entry.ValueB);
                }
                catch (System.Exception ex)
                {
                    Common.ErrorHandler(ex);
                }
            };

            string worksheetTitle = string.Format("{0} & {1}", fileNameA, fileNameB);

            WriteXlsx(outputFileName, enumerator, worksheetTitle, new string[] { "ResourceID", fileNameA, fileNameB }, action);
        }

        /// <summary>
        /// 리소스 내용을 특정 작업을 통해 저장합니다. 
        /// </summary>
        /// <param name="outputFileName">출력파일이름</param>
        /// <param name="enumerator">리소스 테이블의 반복자</param>
        /// <param name="title">워크시트의 이름</param>
        /// <param name="headers">워크시트의 헤더</param>
        /// <param name="action">워크시트에 쓰기 동작</param>
        public static void WriteXlsx(string outputFileName, IDictionaryEnumerator enumerator, string title, string[] headers, Action<HSSFSheet, IDictionaryEnumerator, int> action)
        {
            try
            {
                FileInfo newFile = new FileInfo(outputFileName);
                using (FileStream fs = new FileStream(outputFileName, FileMode.Create))
                {
                    HSSFWorkbook workbook = new HSSFWorkbook();

                    //타이틀 지정 
                    string worksheetTitle = title;
                    HSSFSheet sheet = workbook.CreateSheet(worksheetTitle);

                    //헤더입력
                    int col = 0;
                    foreach (var item in headers)
                    {
                        sheet.Cell(0, col).SetCellValue(item);
                        ++col;
                    }

                    //내용 채우기 
                    int rowIndex = 1;
                    while (enumerator.MoveNext())
                    {
                        try
                        {
                            action(sheet, enumerator, rowIndex);
                        }
                        catch (System.Exception ex)
                        {
                            Console.Beep();
                            Console.WriteLine("Error {0}", ex.Message);
                        }

                        ++rowIndex;
                    }

                    workbook.Write(fs);
                }
            }
            catch (System.Exception ex)
            {
                Common.ErrorHandler(ex);
            }

        }

        #endregion
    }
}
